# --------------------------------------------------------------------

__all__ = ['setup',
           'Extension',
           'config',
           'build',
           'build_src',
           'build_ext',
           'test',
           'sdist',
           ]

# --------------------------------------------------------------------

import sys, os

from conf.baseconf import PetscConfig
from conf.baseconf import setup, Extension, log
from conf.baseconf import config     as _config
from conf.baseconf import build      as _build
from conf.baseconf import build_src  as _build_src
from conf.baseconf import build_ext  as _build_ext
from conf.baseconf import test       as _test
from conf.baseconf import sdist      as _sdist

from distutils.errors import DistutilsError

# --------------------------------------------------------------------


class TaoConfig(PetscConfig):

    def __init__(self, tao_dir, petsc_dir, petsc_arch):
        PetscConfig.__init__(self, petsc_dir, petsc_arch)
        if not tao_dir:
            raise DistutilsError("TAO not found")
        elif not os.path.isdir(tao_dir):
            raise DistutilsError("invalid TAO_DIR")
        self.configdict['TAO_DIR'] = tao_dir
        self.TAO_DIR = self['TAO_DIR']

    def configure_extension(self, extension):
        PetscConfig.configure_extension(self, extension)
        TAO_DIR    = self.TAO_DIR
        PETSC_ARCH = self.PETSC_ARCH
        # define macros
        macros = [('TAO_DIR', TAO_DIR)]
        extension.define_macros.extend(macros)
        # includes and libraries
        TAO_INCLUDE = os.path.join(TAO_DIR, 'include')
        if os.path.exists(os.path.join(TAO_DIR, PETSC_ARCH)):
            TAO_LIB_DIR = os.path.join(TAO_DIR, PETSC_ARCH, 'lib')
        else:
            TAO_LIB_DIR = os.path.join(TAO_DIR, 'lib')
        tao_cfg = { }
        tao_cfg['include_dirs'] = [TAO_INCLUDE]
        tao_cfg['library_dirs'] = [TAO_LIB_DIR]
        tao_cfg['libraries'] = ["tao"] 
        tao_cfg['runtime_library_dirs'] = tao_cfg['library_dirs']
        self._configure_ext(extension, tao_cfg, preppend=True)
        if self['BUILDSHAREDLIB'] == 'no':
            from petsc4py.lib import ImportPETSc
            PETSc = ImportPETSc(PETSC_ARCH)
            extension.extra_objects.append(PETSc.__file__)
        # extra configuration
        cflags = []
        extension.extra_compile_args.extend(cflags)
        lflags = []
        extension.extra_link_args.extend(lflags)

    def log_info(self):
        if not self.TAO_DIR: return
        log.info('TAO_DIR:     %s' % self.TAO_DIR)
        PetscConfig.log_info(self)


# --------------------------------------------------------------------

cmd_tao_opts = [
    ('tao-dir=', None,
     "define TAO_DIR, overriding environmental variable.")
    ]

class config(_config):

    Configure = TaoConfig

    user_options = _config.user_options + cmd_tao_opts

    def initialize_options(self):
        _config.initialize_options(self)
        self.tao_dir  = None

    def get_config_arch(self, arch):
        return config.Configure(self.tao_dir, self.petsc_dir, arch)

    def run(self):
        self.tao_dir  = config.get_tao_dir(self.tao_dir)
        if self.tao_dir is None: return
        log.info('-' * 70)
        log.info('TAO_DIR:     %s' % self.tao_dir)
        _config.run(self)

    #@staticmethod
    def get_tao_dir(tao_dir):
        if not tao_dir: return None
        tao_dir = os.path.expandvars(tao_dir)
        if not tao_dir or '$TAO_DIR' in tao_dir:
            try:
                import tao
                tao_dir = tao.get_tao_dir()
            except ImportError:
                log.warn("TAO_DIR not specified")
                return None
        tao_dir = os.path.expanduser(tao_dir)
        tao_dir = os.path.abspath(tao_dir)
        if not os.path.isdir(tao_dir):
            log.warn('invalid TAO_DIR:  %s' % tao_dir)
            return None
        return tao_dir
    get_tao_dir = staticmethod(get_tao_dir)

class build(_build):

    user_options = _build.user_options + cmd_tao_opts

    def initialize_options(self):
        _build.initialize_options(self)
        self.tao_dir  = None

    def finalize_options(self):
        _build.finalize_options(self)
        self.set_undefined_options('config',
                                   ('tao_dir',  'tao_dir'))
        self.tao_dir = config.get_tao_dir(self.tao_dir)


class build_src(_build_src):
    pass


class build_ext(_build_ext):

    user_options = _build_ext.user_options + cmd_tao_opts

    def initialize_options(self):
        _build_ext.initialize_options(self)
        self.tao_dir  = None

    def finalize_options(self):
        _build_ext.finalize_options(self)
        self.set_undefined_options('build',
                                   ('tao_dir',  'tao_dir'))

    def get_config_arch(self, arch):
        return config.Configure(self.tao_dir, self.petsc_dir, arch)

    def get_config_data(self, arch_list):
        template = """\
TAO_DIR    = %(TAO_DIR)s
PETSC_DIR  = %(PETSC_DIR)s
PETSC_ARCH = %(PETSC_ARCH)s
"""
        variables = {'TAO_DIR'    : self.tao_dir,
                     'PETSC_DIR'  : self.petsc_dir,
                     'PETSC_ARCH' : os.path.pathsep.join(arch_list)}
        return template, variables


class sdist(_sdist):
    pass

class test(_test):
    pass

# --------------------------------------------------------------------
